<template>
  <div class="sport-analysis">
    <div class="sport-container">
      <div class="upload-container">
        <h2>赛事前瞻分析</h2>
        <div v-if="showToast" class="toast-notification">
          {{ toastMessage }}
        </div>
        <div class="format-requirements">
          <div class="format-header">
            <h3>Json格式模版</h3>
            <button class="copy-button" @click="copyTemplate" title="复制模板">
              <DocumentDuplicateIcon class="copy-icon" />
            </button>
          </div>
          <pre class="format-example">
[
  {
    "league": "英冠",
    "match": "斯旺西VS普利茅斯",
    "date": "2025-04-10",
    "time": "02:45:00"
  },
  {
    "league": "英冠",
    "match": "沃特福德VS赫尔城",
    "date": "2025-04-09",
    "time": "02:45:00"
  }
]</pre
          >
        </div>

        <div class="upload-area">
          <input
            type="file"
            id="jsonFile"
            accept=".json"
            @change="handleFileChange"
            :disabled="isProcessing"
          />
          <label for="jsonFile" class="upload-button">
            <span v-if="!selectedFile">选择JSON文件</span>
            <span v-else>{{ selectedFile.name }}</span>
          </label>

          <!-- 新增风格选择下拉框 -->
          <div class="style-selector">
            <button
              class="style-toggle"
              @click="showStyleDropdown = !showStyleDropdown"
              :disabled="isProcessing || styles.length === 0"
            >
              风格选择 ({{ selectedStyles.length }})
            </button>
            <div
              v-if="showStyleDropdown"
              class="style-dropdown"
              @click.stop
            >
              <div
                v-for="style in styles"
                :key="style.name"
                class="style-option"
              >
                <input
                  type="checkbox"
                  :id="'style-' + style.name"
                  :checked="selectedStyles.includes(style.name)"
                  @change="toggleStyle(style.name)"
                  class="style-checkbox"
                />
                <label :for="'style-' + style.name">{{ style.displayName }}</label>
              </div>
            </div>
          </div>

          <button
            class="analyze-button"
            @click="analyzeFile"
            :disabled="!selectedFile || selectedStyles.length === 0"
          >
            {{ isProcessing ? '停止分析' : '开始分析' }}
          </button>
        </div>

        <div v-if="progress > 0" class="progress-container">
          <div class="progress-bar">
            <div class="progress" :style="{ width: `${progress}%` }"></div>
          </div>
          <span class="progress-text">{{ progress }}%</span>
        </div>

        <div v-if="analysisResult" class="result-container">
          <div class="result-preview">
            <div class="result-header">
              <h3>分析结果预览</h3>
              <button class="copy-button" @click="copyResult" title="复制结果">
                <DocumentDuplicateIcon class="copy-icon" />
              </button>
            </div>
            <pre>{{ analysisResult }}</pre>
          </div>
          <button class="download-button" @click="downloadResult">下载</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { DocumentDuplicateIcon } from '@heroicons/vue/24/outline'

const selectedFile = ref(null)
const isProcessing = ref(false)
const progress = ref(0)
const analysisResult = ref(null)

const styles = ref([])
const selectedStyles = ref([])
const showStyleDropdown = ref(false)
const cancelToken = ref(null)

const handleFileChange = (event) => {
  const file = event.target.files[0]
  if (file && file.type === 'application/json') {
    analysisResult.value = null
    resultBlob.value = null
    resultFileName.value = ''
    progress.value = 0
    selectedFile.value = file
  } else {
    // 使用模态框代替 alert
    showNotification('请选择有效的JSON文件')
  }
  event.target.value = ''
}

// 新增方法：获取所有风格
const fetchStyles = async () => {
  try {
    // 使用相对路径，Vite 代理会自动转发到后端
    const response = await fetch('/sport/styles')
    if (response.ok) {
      styles.value = await response.json()
      // 默认选择第一个风格
      if (styles.value.length > 0) {
        selectedStyles.value = [styles.value[0].name]
      }
    } else {
      const error = await response.text()
      throw new Error(error || '获取风格失败')
    }
  } catch (error) {
      console.error('获取风格失败:', error)
      showNotification(`获取风格失败: ${error.message}`)
  }
}

const toggleStyle = (styleName) => {
  const index = selectedStyles.value.indexOf(styleName)
  if (index === -1) {
    selectedStyles.value.push(styleName)
  } else {
    selectedStyles.value.splice(index, 1)
  }
}

const analyzeFile = async () => {
  if (selectedStyles.value.length === 0) {
    showNotification('请至少选择一种风格')
    return
  }

  if (isProcessing.value) {
    cancelToken.value = true
    isProcessing.value = false
    progress.value = 0
    return
  }

  if (!selectedFile.value) return

  isProcessing.value = true
  progress.value = 0
  cancelToken.value = false
  analysisResult.value = null

  try {
    const formData = new FormData()
    formData.append('file', selectedFile.value)
    selectedStyles.value.forEach((style) => {
      formData.append('styles', style)
    })

    const fileContent = await new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.onload = () => resolve(reader.result)
      reader.onerror = reject
      reader.readAsText(selectedFile.value)
    })

    const jsonListLength = JSON.parse(fileContent).length
    const styleLength = selectedStyles.value.length
    const totalTimeInSeconds = jsonListLength * 60 * styleLength
    // 上传进度
    const interval = setInterval(() => {
      if (cancelToken.value) {
        clearInterval(interval)
        return
      }
      const intervalTime = 700
      const incrementPerInterval = (100 / totalTimeInSeconds) * (intervalTime / 1000)
      if (progress.value < 99.9) {
        progress.value += incrementPerInterval
        progress.value = parseFloat(progress.value.toFixed(2));
      } else {
        progress.value = 99.9;
      }
    }, 700)

    const controller = new AbortController()
    const signal = controller.signal

    if (cancelToken.value) {
      controller.abort()
      return
    }

    // 使用相对路径，Vite 代理会自动转发到后端
    const response = await fetch('/sport/analysis/json', {
      method: 'POST',
      body: formData,
      signal,
    })

    clearInterval(interval)
    progress.value = 100

    if (response.ok) {
      // 保存返回的文件流，不立即下载
      resultBlob.value = await response.blob()

      // 获取文件名
      const contentDisposition = response.headers.get('content-disposition')
      resultFileName.value = 'analysis_result.md'
      if (contentDisposition) {
        const matches = contentDisposition.match(/filename="(.+)"/)
        if (matches && matches[1]) {
          resultFileName.value = matches[1]
        }
      }

      // 读取文件内容用于预览
      const text = await resultBlob.value.text()
      analysisResult.value = text
    } else {
      const error = await response.text()
      throw new Error(error || '分析失败')
    }
  } catch (error) {
    if (error.name !== 'AbortError') {
      console.error('分析错误:', error)
      showNotification(error.message || '分析过程中出现错误')
    }
  } finally {
    isProcessing.value = false
  }
}
onMounted(() => {
  fetchStyles()
  // 添加点击外部关闭下拉框的监听器
  document.addEventListener('click', closeStyleDropdown)
})

// 添加这两个ref用于存储下载数据
const resultBlob = ref(null)
const resultFileName = ref('')

const downloadResult = () => {
  if (!resultBlob.value) return

  const url = URL.createObjectURL(resultBlob.value)
  const a = document.createElement('a')
  a.href = url
  a.download = resultFileName.value
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
}

const toastMessage = ref('')
const showToast = ref(false)

const showNotification = (message) => {
  toastMessage.value = message
  showToast.value = true
  setTimeout(() => {
    showToast.value = false
  }, 1000)
}

const copyToClipboard = (text, successMessage, errorMessage) => {
  // 检查 navigator.clipboard 是否可用
  if (navigator.clipboard && navigator.clipboard.writeText) {
    navigator.clipboard
      .writeText(text)
      .then(() => showNotification(successMessage))
      .catch(() => {
        console.error('Failed to copy using navigator.clipboard. Trying fallback.')
        fallbackCopyToClipboard(text, successMessage, errorMessage)
      })
  } else {
    // 降级使用 document.execCommand
    fallbackCopyToClipboard(text, successMessage, errorMessage)
  }
}

const fallbackCopyToClipboard = (text, successMessage, errorMessage) => {
  const textarea = document.createElement('textarea')
  textarea.value = text
  textarea.style.position = 'fixed' // 避免滚动
  textarea.style.opacity = 0
  document.body.appendChild(textarea)
  textarea.focus()
  textarea.select()
  try {
    const successful = document.execCommand('copy')
    const message = successful ? successMessage : errorMessage
    showNotification(message)
  } catch (err) {
    console.error('Fallback copy failed', err)
    showNotification(errorMessage)
  } finally {
    document.body.removeChild(textarea)
  }
}

const copyTemplate = () => {
  const template = `[
  {
    "league": "英冠",
    "match": "斯旺西VS普利茅斯",
    "date": "2025-04-10",
    "time": "02:45:00"
  },
  {
    "league": "英冠",
    "match": "沃特福德VS赫尔城",
    "date": "2025-04-09",
    "time": "02:45:00"
  }
]`
  copyToClipboard(template, '复制成功', '复制失败')
}

const copyResult = () => {
  if (!analysisResult.value) return
  copyToClipboard(analysisResult.value, '分析结果已复制', '复制失败')
}

// 新增函数：点击外部关闭下拉框
const closeStyleDropdown = (event) => {
  if (showStyleDropdown.value && !event.target.closest('.style-selector')) {
    showStyleDropdown.value = false
  }
}
</script>

<style scoped lang="scss">
.toast-notification {
  position: fixed;
  top: 8%;
  left: 50%;
  transform: translateX(-50%);
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 12px 24px;
  border-radius: 4px;
  z-index: 1000;
  animation: fadeInOut 1s ease-in-out forwards;
}

@keyframes fadeInOut {
  0% {
    opacity: 0;
    transform: translateX(-50%) translateY(20px);
  }

  20% {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }

  80% {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }

  100% {
    opacity: 0;
    transform: translateX(-50%) translateY(-20px);
  }
}

.dark .toast-notification {
  background-color: rgba(255, 255, 255, 0.9);
  color: #333;
}

.sport-analysis {
  position: fixed;
  top: 64px;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  background: var(--bg-color);
  overflow: auto;
  z-index: 1;

  .sport-container {
    flex: 1;
    display: flex;
    flex-direction: column;
    max-width: 1200px;
    width: 100%;
    margin: 0 auto;
    padding: 2rem;
  }

  .upload-container {
    background: white;
    border-radius: 12px;
    padding: 2rem;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    max-width: 800px;
    margin: 0 auto;
    width: 100%;

    h2 {
      text-align: center;
      color: #333;
      margin-bottom: 2rem;
      font-size: 1.8rem;
    }

    .format-requirements {
      margin-bottom: 2rem;
      background: #f8f9fa;
      padding: 1rem;
      border-radius: 8px;
      border: 1px solid #e9ecef;

      h3 {
        margin-top: 0;
        color: #495057;
        font-size: 1.1rem;
      }

      .format-example {
        background: #f1f3f5;
        padding: 1rem;
        border-radius: 4px;
        overflow-x: auto;
        font-family: 'Courier New', monospace;
        color: #495057;
        white-space: pre-wrap;
      }
    }

    .upload-area {
      display: flex;
      gap: 1rem;
      margin-bottom: 2rem;
      align-items: center;
      position: relative;

      .style-selector {
        position: relative;

        .style-toggle {
          padding: 0.75rem 1rem;
          background: #f8f9fa;
          border: 1px solid #e9ecef;
          border-radius: 8px;
          cursor: pointer;
          transition: all 0.2s;
          min-width: 120px; /* 增加宽度以适应新内容 */
          text-align: center; /* 居中显示 */

          &:hover:not(:disabled) {
            background: #e9ecef;
          }

          &:disabled {
            opacity: 0.6;
            cursor: not-allowed;
          }
        }

        .style-dropdown {
          position: absolute;
          top: 100%;
          left: 0;
          width: 200px;
          background: white;
          border: 1px solid #e9ecef;
          border-radius: 8px;
          box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
          z-index: 10;
          /* 移除滚动条，如果内容过多会溢出 */
          /* max-height: 300px; */
          /* overflow-y: auto; */
          margin-top: 0.5rem;
        }

        .style-option {
          padding: 0.5rem 1rem;
          display: flex;
          align-items: center;
          cursor: pointer;
          transition: background-color 0.2s;
          width: 100%;

          &:hover {
            background: #f8f9fa;
          }
          
          .style-checkbox {
            margin-right: 0.5rem;
          }
          label {
            flex: 1;
            cursor: pointer;
          }
        }
      }

      input[type='file'] {
        display: none;
      }

      .upload-button {
        flex: 1;
        padding: 0.75rem 1rem;
        background: #f8f9fa;
        border: 1px dashed #adb5bd;
        border-radius: 8px;
        text-align: center;
        cursor: pointer;
        transition: all 0.2s;

        &:hover {
          background: #e9ecef;
          border-color: #6c757d;
        }
      }

      .analyze-button {
        padding: 0.75rem 1.5rem;
        background: #007cf0;
        color: white;
        border: none;
        border-radius: 8px;
        font-weight: 500;
        cursor: pointer;
        transition: background-color 0.2s;

        &:hover:not(:disabled) {
          background: #0066cc;
        }

        &:disabled {
          background: #adb5bd;
          cursor: not-allowed;
        }
      }
    }

    .progress-container {
      margin-bottom: 2rem;
      display: flex;
      align-items: center;
      gap: 1rem;

      .progress-bar {
        flex: 1;
        height: 8px;
        background: #e9ecef;
        border-radius: 4px;
        overflow: hidden;

        .progress {
          height: 100%;
          background: #007cf0;
          transition: width 0.3s ease;
        }
      }

      .progress-text {
        font-size: 0.9rem;
        color: #495057;
      }
    }

    .dark {
      .format-header,
      .result-header {
        .copy-button {
          color: #63b3ff;

          &:hover {
            color: #4299e1;
          }
        }
      }
    }

    .format-header,
    .result-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      position: relative;

      h3 {
        margin: 0;
      }

      .copy-button {
        position: absolute;
        right: -10px; // 根据实际布局微调
        top: 50%;
        transform: translateY(-50%);
        background: none;
        border: none;
        padding: 8px;
        cursor: pointer;
        color: #007cf0;

        &:hover {
          color: #0066cc;
        }

        .copy-icon {
          width: 1.2rem;
          height: 1.2rem;
        }
      }
    }

    .result-container {
      border-top: 1px solid #e9ecef;
      padding-top: 1.5rem;

      .result-preview {
        margin-bottom: 1.5rem;

        h3 {
          margin-top: 0;
          color: #495057;
        }

        pre {
          background: #f8f9fa;
          padding: 1rem;
          border-radius: 8px;
          max-height: 300px;
          overflow-y: auto;
          font-family: 'Courier New', monospace;
          white-space: pre-wrap;
        }
      }

      .download-button {
        padding: 0.75rem 1.5rem;
        background: #28a745;
        color: white;
        border: none;
        border-radius: 8px;
        font-weight: 500;
        cursor: pointer;
        transition: background-color 0.2s;

        &:hover {
          background: #218838;
        }
      }
    }
  }
}

.dark {
  .upload-container {
    background: #2d3748;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);

    h2 {
      color: #e2e8f0;
    }

    .format-requirements {
      background: #4a5568;
      border-color: #4a5568;

      h3 {
        color: #e2e8f0;
      }

      .format-example {
        background: #2d3748;
        color: #e2e8f0;
      }
    }

    .upload-area {
      .upload-button {
        background: #4a5568;
        border-color: #4a5568;
        color: #e2e8f0;

        &:hover {
          background: #2d3748;
        }
      }
    }

    .progress-container {
      .progress-bar {
        background: #4a5568;
      }

      .progress-text {
        color: #e2e8f0;
      }
    }

    .result-container {
      border-color: #4a5568;

      .result-preview {
        h3 {
          color: #e2e8f0;
        }

        pre {
          background: #2d3748;
          color: #e2e8f0;
        }
      }
    }
  }
}

.preview-options {
  display: flex;
  gap: 1rem;
  margin-bottom: 1rem;

  .preview-button {
    padding: 0.5rem 1rem;
    background: #6c757d;
    color: white;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    transition: background-color 0.2s;

    &:hover {
      background: #5a6268;
    }
  }
}

.preview-content {
  margin-top: 1rem;
  background: #f8f9fa;
  padding: 1rem;
  border-radius: 8px;
  max-height: 300px;
  overflow-y: auto;
}

.file-info {
  display: flex;
  align-items: center;
  margin-top: 1rem;
  padding: 0.5rem;
  background: #f1f3f5;
  border-radius: 6px;

  .file-icon {
    width: 1.2rem;
    height: 1.2rem;
    margin-right: 0.5rem;
    color: #495057;
  }

  .file-name {
    flex: 1;
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .file-size {
    font-size: 0.8rem;
    color: #6c757d;
    margin-left: 0.5rem;
  }
}

.dark {
  .preview-content {
    background: #2d3748;
    color: #e2e8f0;
  }

  .file-info {
    background: #4a5568;

    .file-icon {
      color: #e2e8f0;
    }

    .file-size {
      color: #a0aec0;
    }
  }
}
.dark {
  .upload-area {
    .style-toggle {
      background: #4a5568;
      border-color: #4a5568;
      color: #e2e8f0;

      &:hover:not(:disabled) {
        background: #2d3748;
      }
    }

    .style-dropdown {
      background: #2d3748;
      border-color: #4a5568;
    }

    .style-option {
      &:hover {
        background: #4a5568;
      }
    }
  }
}
</style>
